# -*- coding: UTF-8 -*-

'''
Created on 03.02.2013

@author: Peter Heß
'''
import unittest
from spreads.LinearSpreadGen import LinearSpread 
from spreads.LinearSpreadGen import SpreadType
from compiler.pycodegen import EXCEPT
from array import *

class Test(unittest.TestCase):

    def feq(self,a,b):
        if abs(a-b)<0.0001:
            return True
        else:
            return False


    def setUp(self):
        pass


    def tearDown(self):
        pass


    def testIsLenCorrect(self):
        ls = LinearSpread(SpreadCount_in=[10], SpreadType_in=[SpreadType.LeftJustified])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testSpreadCountZero")
        self.assertIs(10, len(spread));
        pass


    def testIsLenCorrect2(self):
        ls = LinearSpread(Input_in= [-0.5], SpreadCount_in=[10])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testIsLenCorrect2")
        self.assertIs(10, len(spread));
        pass
    

    def testSpreadCountZero(self):
        ls = LinearSpread(SpreadCount_in=[0], SpreadType_in=[SpreadType.LeftJustified])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testSpreadCountZero")
        ls.dumpSpread(msg="testSpreadCountZero")
        self.assertIs(0, len(spread))
        pass


    def testWrongSpreadType(self):
        '''Call a wrong SpreadType. The constructor must throw an AttributeError'''
        ls = None
        try:
            ls = LinearSpread(SpreadCount_in=[10], SpreadType_in=[-1])
            ls.update()
            self.fail("Exception not handled.")
        except AttributeError:
            print "Exception catched"
            ls = LinearSpread(SpreadCount_in=[10])
            ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testWrongSpreadType")
        self.assertIs(10, len(spread));
        pass
    
    def testLeftJustified(self):
        expected = array('f', [-0.5000, -0.4000, -0.3000, -0.2000, -0.1000, 
                               0.0000, 0.1000, 0.2000, 0.3000, 0.4000])
        ls = LinearSpread(SpreadCount_in=[10], SpreadType_in=[SpreadType.LeftJustified])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testLeftJustified")
        self.assertIs(10, len(spread));
        # ls.dumpSpread(msg="testLeftJustified")
        for i in range(10):
            # print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass
    
    def testLeftJustifiedMitInputOffset(self):
        expected = array('f', [-.2, 0.1333, 0.4667])
        ls = LinearSpread(Input_in=[0.3], SpreadCount_in=[3], SpreadType_in=[SpreadType.LeftJustified])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testLeftJustifiedMitInputOffset")
        self.assertIs(3, len(spread));
        ls.dumpSpread(msg="testLeftJustifiedMitInputOffset")
        for i in range(3):
            # print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass
    
    def testLeftJustified11(self):
        expected = array('f', [-0.5000, -0.4091, -0.3182, -0.2273, -0.1364, -0.0455, 
                               0.0455, 0.1364, 0.2273, 0.3182, 0.4091])
        ls = LinearSpread(SpreadCount_in=[11], SpreadType_in=[SpreadType.LeftJustified])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testLeftJustified11")
        self.assertIs(11, len(spread));
        # ls.dumpSpread(msg="testLeftJustified11")
        for i in range(11):
            # print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass


    def testRigthJustified(self):
        expected = array('f', [-0.4000, -0.3000, -0.2000, -0.1000, 0.0000, 0.1000, 0.2000, 0.3000, 0.4000, 0.5000])
        ls = LinearSpread(SpreadCount_in=[10], SpreadType_in=[SpreadType.RightJustified])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testRigthJustified")
        self.assertIs(10, len(spread));
        # ls.dumpSpread(msg="testLeftJustified")
        for i in range(10):
            # print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass
    
    def testRigthJustifiedMitOffset(self):
        expected = array('f', [0.1333, 0.4667, 0.8000])
        ls = LinearSpread(Input_in=[0.3], SpreadCount_in=[3], SpreadType_in=[SpreadType.RightJustified])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testRigthJustifiedMitOffset")
        self.assertIs(3, len(spread));
        # ls.dumpSpread(msg="testLeftJustified")
        for i in range(3):
            # print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass

    def testRigthJustified11(self):
        expected = array('f', [-0.4091, -0.3182, -0.2273, -0.1364, -0.0455, 0.0455, 0.1364, 0.2273, 0.3182, 0.4091, 0.5000])
        ls = LinearSpread(SpreadCount_in=[11], SpreadType_in=[SpreadType.RightJustified])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testRigthJustified11")
        self.assertIs(11, len(spread));
        # ls.dumpSpread(msg="testRigthJustified11")
        for i in range(11):
            print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass

    
    def testCentered10(self):
        expected = array('f', [-0.4500, -0.3500, -0.2500, -0.1500, -0.0500, 0.0500, 0.1500, 0.2500, 0.3500, 0.4500])
        ls = LinearSpread(SpreadCount_in=[10], SpreadType_in=[SpreadType.Centered])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testCentered10")
        self.assertIs(10, len(spread));
        # ls.dumpSpread(msg="testCentered10")
        for i in range(10):
            # print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass


    def testCentered11(self):
        expected = array('f', [-0.4545, -0.3636, -0.2727, -0.1818, -0.0909, 0.0000, 0.0909, 0.1818, 0.2727, 0.3636, 0.4545])
        ls = LinearSpread(SpreadCount_in=[11], SpreadType_in=[SpreadType.Centered])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testCentered11")
        self.assertIs(11, len(spread));
        # ls.dumpSpread(msg="testCentered11")
        for i in range(11):
            # print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass

    def testCentered11_3values(self):
        expected = array('f', [-0.0333, 0.3000, 0.6333])
        ls = LinearSpread(Input_in=[0.3],SpreadCount_in=[3], SpreadType_in=[SpreadType.Centered])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testCentered11_3values")
        self.assertIs(3, len(spread));
        # ls.dumpSpread(msg="testCentered11")
        for i in range(3):
            # print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass

    def testBlock(self):
        expected = array('f', [-0.5000, -0.4000, -0.3000, -0.2000, -0.1000, 
                               0.0000, 0.1000, 0.2000, 0.3000, 0.4000, 0.5000])
        ls = LinearSpread(SpreadCount_in=[11], SpreadType_in=[SpreadType.Block])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testBlock")
        self.assertIs(11, spread.size);
        for i in range(11):
            # print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass

    def testBlockWithOffset(self):
        expected = array('f', [ -0.2000, 0.3000, 0.8000])
        ls = LinearSpread(Input_in=[0.3],SpreadCount_in=[3], SpreadType_in=[SpreadType.Block])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testBlockWithOffset")
        self.assertIs(3, spread.size);
        for i in range(3):
            # print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass


    def testCenteredWithPhase(self):
        
        ls = LinearSpread(SpreadCount_in=[10], SpreadType_in=[SpreadType.Centered])
        ls.update()
        spread = ls.Output
        ls.dumpSetup(msg="testBlock")
        print ls.Output
        self.assertIs(10, len(spread));
        self.assertTrue(self.feq(-0.4500, ls.Output[0]), "first element")
        ls.update(Phase_in=[0.1])
        print ls.Output
        self.assertTrue(self.feq(-0.3500, ls.Output[0]), "first element")
        ls.update(Phase_in=[0.2])
        print ls.Output
        self.assertTrue(self.feq(-0.2500, ls.Output[0]), "first element")

    def testSpreadInputWithSpread(self):
        expected = array('f', [-0.0333, 0.3000, 0.6333, -0.3333, 0.0000, 0.3333, -1.0333, -0.7000, -0.3667])
        ls = LinearSpread(Input_in=[0.3, 0.0, -0.7], SpreadCount_in=[3], Width_in=[1.0], SpreadType_in=[SpreadType.Centered])
        ls.update()
        ls.dumpSetup(msg="testSpreadInputWithSpread")
        spread = ls.Output
        self.assertIs(9, len(spread));
        for i in range(9):
            print str(expected[i]) + " " + str(spread[i])
            self.assertTrue( self.feq(expected[i], spread[i]), "i=" + str(i))
        pass
       
if __name__ == "__main__":
    # import sys;sys.argv = ['', 'Test.testName']
    unittest.main()
